﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace AMS.Common
{
    /// <summary>
    /// 读取或写入INI文件
    /// </summary>
    public class IniFile
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        public IniFile(string fileName)
        {
            path = fileName;
        }

        /// <summary>
        /// 文件INI名称 
        /// </summary>
        private string path;

        #region Native的方法
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string errstr, StringBuilder outstr, uint strlong, string filePath);
        [DllImport("Kernel32")]
        private static extern int GetPrivateProfileSectionNames(byte[] buffer, int size, string fileName);
        [DllImport("Kernel32")]
        private static extern int GetPrivateProfileSection(string section, byte[] buffer, int size, string fileName);
        #endregion

        /// <summary>
        /// 写INI文件
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        public void WriteValue(string section, string key, string value)
        {
            WritePrivateProfileString(section, key, value, this.path);
        }

        /// <summary>
        /// 读INI文件的值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string ReadValue(string section, string key)
        {
            return ReadValue(section, key, null);
        }

        /// <summary>
        /// 读取INI文件的值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string ReadValue(string section, string key, string defaultValue)
        {
            StringBuilder temp = new StringBuilder(4096);
            int i = GetPrivateProfileString(section, key, "", temp, 4096, this.path);
            if (i == 0)
            {
                return defaultValue;
            }
            else
            {
                return temp.ToString();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public int ReadIntValue(string section, string key, int defaultValue)
        {
            string retValue = ReadValue(section, key, null);
            int value = 0;
            if (string.IsNullOrEmpty(retValue) || !int.TryParse(retValue,  out value))
            {
                return defaultValue;
            }

            return value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public double ReadDoubleValue(string section, string key, double defaultValue)
        {
            string retValue = ReadValue(section, key, null);
            double value = 0;
            if (string.IsNullOrEmpty(retValue) || !double.TryParse(retValue, out value))
            {
                return defaultValue;
            }

            return value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="section"></param>
        /// <returns></returns>
        public bool IsSectionExists(string section)
        {
            int size = 8192;
            byte[] bytes = new byte[size];
            int realSize = GetPrivateProfileSection(section, bytes, size, path);

            if (realSize <= 0)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 获取所有的分组
        /// </summary>
        /// <returns></returns>
        public string[] GetSectionNames()
        {
            byte[] bytes = new byte[4096];
            int realSize = GetPrivateProfileSectionNames(bytes, 4096, path);

            if (realSize <= 0)
            {
                return null;
            }

            List<string> sections = new List<string>();
            int lastIndex = 0;
            for (int i = 0; i < realSize; i++)
            {
                if (bytes[i] > 0) continue;

                string section = Encoding.Default.GetString(bytes, lastIndex, i - lastIndex);
                sections.Add(section);
                lastIndex = i + 1;
            }

            return sections.ToArray();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="section"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetSectionContent(string section)
        {
            int size = 8192;
            byte[] bytes = new byte[size];
            int realSize = GetPrivateProfileSection(section, bytes, size, path);

            if (realSize <= 0)
            {
                return null;
            }

            Dictionary<string, string> keyValues = new Dictionary<string, string>();
            int lastIndex = 0;
            for (int i = 0; i < realSize; i++)
            {
                if (bytes[i] > 0) continue;

                string pair = Encoding.Default.GetString(bytes, lastIndex, i - lastIndex);

                string[] token = pair.Split('=');
                if (token.Length == 2)
                {
                    keyValues.Add(token[0], token[1]);
                }

                lastIndex = i + 1;
            }

            return keyValues;
        }

    }
}
